home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Archives / GNU / GNUPLOTsrc.lha / term / post.trm < prev    next >
Encoding:
Text File  |  1996-01-22  |  47.4 KB  |  1,467 lines

  1. /*
  2.  * $Id: post.trm,v 1.22 1995/12/20 22:39:51 drd Exp $
  3.  */
  4.  
  5. /* GNUPLOT - post.trm */
  6. /*
  7.  * Copyright (C) 1990 - 1993   
  8.  *
  9.  * Permission to use, copy, and distribute this software and its
  10.  * documentation for any purpose with or without fee is hereby granted, 
  11.  * provided that the above copyright notice appear in all copies and 
  12.  * that both that copyright notice and this permission notice appear 
  13.  * in supporting documentation.
  14.  *
  15.  * Permission to modify the software is granted, but not the right to
  16.  * distribute the modified code.  Modifications are to be distributed 
  17.  * as patches to released version.
  18.  *  
  19.  * This software  is provided "as is" without express or implied warranty.
  20.  * 
  21.  * This terminal driver supports:
  22.  *     postscript
  23.  *
  24.  * AUTHORS
  25.  *  Russell Lang
  26.  *
  27.  * modified 10/5/95 by drd - put in support for other postscript drivers
  28.  * (enhpost, pslatex, ...) so they dont have to work quite so hard
  29.  * 
  30.  * send your comments or suggestions to (info-gnuplot@dartmouth.edu).
  31.  *
  32.  * The 'postscript' driver produces landscape output 10" wide and 7" high.  
  33.  * To change font to Times-Roman and font size to 20pts use 
  34.  * 'set term postscript "Times-Roman" 20'.
  35.  * To get a smaller (5" x 3.5") eps output use 'set term post eps'
  36.  * and make only one plot per file.  Font size for eps will be half
  37.  * the specified size.
  38.  */
  39.  
  40. #ifndef GOT_DRIVER_H
  41. #include "driver.h"
  42. #endif
  43.  
  44. #ifdef TERM_REGISTER
  45. register_term(post)
  46. #endif
  47.  
  48. #ifdef TERM_PROTO
  49. TERM_PUBLIC void PS_options __P((void));
  50. TERM_PUBLIC void PS_common_init __P((int encap, int portrait, int uses_fonts, unsigned int xoff, unsigned int yoff, unsigned int bb_xmin, unsigned int bb_ymin, unsigned int bb_xmax, unsigned int bb_ymax, char **dict));
  51. TERM_PUBLIC void PS_init __P((void));
  52. TERM_PUBLIC void PS_graphics __P((void));
  53. TERM_PUBLIC void PS_text __P((void));
  54. TERM_PUBLIC void PS_reset __P((void));
  55. TERM_PUBLIC void PS_linetype __P((int linetype));
  56. TERM_PUBLIC void PS_move __P((unsigned int x, unsigned int y));
  57. TERM_PUBLIC void PS_vector __P((unsigned int x, unsigned int y));
  58. TERM_PUBLIC void PS_put_text __P((unsigned int x, unsigned int y, char *str));
  59. TERM_PUBLIC int PS_text_angle __P((int ang));
  60. TERM_PUBLIC int PS_justify_text __P((enum JUSTIFY mode));
  61. TERM_PUBLIC void PS_point __P((unsigned int x, unsigned int y, int number));
  62. TERM_PUBLIC int PS_set_font __P((char * font));
  63. TERM_PUBLIC void PS_set_pointsize __P((double size));
  64.  
  65. #define PS_POINT_TYPES 8
  66. #define PS_XOFF    50    /* page offset in pts */
  67. #define PS_YOFF    50
  68. #define PS_XMAX 7200 /* assumes landscape */
  69. #define PS_YMAX 5040
  70. #define PS_XLAST (PS_XMAX - 1)
  71. #define PS_YLAST (PS_YMAX - 1)
  72. #define PS_VTIC (PS_YMAX/80)
  73. #define PS_HTIC (PS_YMAX/80)
  74. #define PS_SC (10)                /* scale is 1pt = 10 units */
  75. #define    PS_LW (0.5*PS_SC)        /* linewidth = 0.5 pts */
  76. #define PS_VCHAR (14*PS_SC)        /* default is 14 point characters */
  77. #define PS_HCHAR (14*PS_SC*6/10)
  78.  
  79. #define GOT_POST_PROTO
  80. #endif
  81.  
  82.  
  83. #ifndef TERM_PROTO_ONLY
  84.  
  85. #ifdef TERM_BODY
  86. /* PostScript driver by Russell Lang, rjl@monu1.cc.monash.edu.au */
  87.  
  88. static char *PS_RememberFont __P((char *fname, int reencode));
  89. static void ENHPS_put_text __P((unsigned int x, unsigned int y, char *str));
  90. static char *ENHPS_recurse __P((char *p, TBOOLEAN brace, char *fontname, double fontsize, double base, TBOOLEAN widthflag, TBOOLEAN showflag));
  91. static char ps_font[MAX_ID_LEN+1] = "Helvetica" ; /* name of font */
  92. static int ps_fontsize = 14;                     /* size of font in pts */
  93. static TBOOLEAN ps_portrait = FALSE;                 /* vertical page */
  94. static TBOOLEAN ps_color = FALSE;
  95. static TBOOLEAN ps_solid = FALSE;           /*  use solid lines */
  96. static TBOOLEAN ps_eps = FALSE;    /* Is this for an eps file? */
  97.             /* Added by Robert Davis <davis@ecn.purdue.edu> */
  98. static int ps_page=0;            /* page count */
  99. static int ps_path_count=0;     /* count of lines in path */
  100. static int ps_ang=0;            /* text angle */
  101. static enum JUSTIFY ps_justify=LEFT;    /* text is flush left */
  102.  
  103. /* added by Matt Heffron <heffron@falstaff.css.beckman.com> */
  104. static TBOOLEAN ps_duplex_state = FALSE;
  105. static TBOOLEAN ps_duplex_option = FALSE;
  106.  
  107. static char GPFAR * GPFAR PS_header[] = {
  108. "/M {moveto} bind def\n",
  109. "/L {lineto} bind def\n",
  110. "/R {rmoveto} bind def\n",
  111. "/V {rlineto} bind def\n",
  112. "/vpt2 vpt 2 mul def\n",
  113. "/hpt2 hpt 2 mul def\n",
  114. /* flush left show */
  115. "/Lshow { currentpoint stroke M\n",
  116. "  0 vshift R show } def\n", 
  117. /* flush right show */
  118. "/Rshow { currentpoint stroke M\n",
  119. "  dup stringwidth pop neg vshift R show } def\n", 
  120. /* centred show */
  121. "/Cshow { currentpoint stroke M\n",
  122. "  dup stringwidth pop -2 div vshift R show } def\n", 
  123. /* Dash or Color Line */
  124. "/DL { Color {setrgbcolor Solid {pop []} if 0 setdash }\n",
  125. " {pop pop pop Solid {pop []} if 0 setdash} ifelse } def\n",
  126. /* Border Lines */
  127. "/BL { stroke gnulinewidth 2 mul setlinewidth } def\n",
  128. /* Axes Lines */
  129. "/AL { stroke gnulinewidth 2 div setlinewidth } def\n",
  130. /* Plot Lines */
  131. "/PL { stroke gnulinewidth setlinewidth } def\n",
  132. /* Line Types */
  133. "/LTb { BL [] 0 0 0 DL } def\n", /* border */
  134. "/LTa { AL [1 dl 2 dl] 0 setdash 0 0 0 setrgbcolor } def\n", /* axes */
  135. "/LT0 { PL [] 0 1 0 DL } def\n",
  136. "/LT1 { PL [4 dl 2 dl] 0 0 1 DL } def\n",
  137. "/LT2 { PL [2 dl 3 dl] 1 0 0 DL } def\n",
  138. "/LT3 { PL [1 dl 1.5 dl] 1 0 1 DL } def\n",
  139. "/LT4 { PL [5 dl 2 dl 1 dl 2 dl] 0 1 1 DL } def\n",
  140. "/LT5 { PL [4 dl 3 dl 1 dl 3 dl] 1 1 0 DL } def\n",
  141. "/LT6 { PL [2 dl 2 dl 2 dl 4 dl] 0 0 0 DL } def\n",
  142. "/LT7 { PL [2 dl 2 dl 2 dl 2 dl 2 dl 4 dl] 1 0.3 0 DL } def\n",
  143. "/LT8 { PL [2 dl 2 dl 2 dl 2 dl 2 dl 2 dl 2 dl 4 dl] 0.5 0.5 0.5 DL } def\n",
  144. /* Point (Round) */    /* Matt Heffron make it round */
  145. "/Pnt { stroke [] 0 setdash\n",
  146. "   gsave 1 setlinecap M 0 0 V stroke grestore } def\n",
  147.  
  148. /* Diamond */
  149. "/Dia { stroke [] 0 setdash 2 copy vpt add M\n",
  150. "  hpt neg vpt neg V hpt vpt neg V\n",
  151. "  hpt vpt V hpt neg vpt V closepath stroke\n",
  152. "  Pnt } def\n",
  153.  
  154. /* Plus */
  155. "/Pls { stroke [] 0 setdash vpt sub M 0 vpt2 V\n",
  156. "  currentpoint stroke M\n",
  157. "  hpt neg vpt neg R hpt2 0 V stroke\n",
  158. "  } def\n",
  159.  
  160. /* Box */
  161. "/Box { stroke [] 0 setdash 2 copy exch hpt sub exch vpt add M\n",
  162. "  0 vpt2 neg V hpt2 0 V 0 vpt2 V\n",
  163. "  hpt2 neg 0 V closepath stroke\n",
  164. "  Pnt } def\n",
  165.  
  166. /* Cross (X) */
  167. "/Crs { stroke [] 0 setdash exch hpt sub exch vpt add M\n",
  168. "  hpt2 vpt2 neg V currentpoint stroke M\n",
  169. "  hpt2 neg 0 R hpt2 vpt2 V stroke } def\n",
  170.  
  171. /* Triangle Up*/
  172. "/TriU { stroke [] 0 setdash 2 copy vpt 1.12 mul add M\n",
  173. "  hpt neg vpt -1.62 mul V\n",
  174. "  hpt 2 mul 0 V\n",
  175. "  hpt neg vpt 1.62 mul V closepath stroke\n",
  176. "  Pnt  } def\n",
  177.  
  178. /* Star */
  179. "/Star { 2 copy Pls Crs } def\n",
  180.  
  181. /* div added filed box */
  182. /* Filled Box */
  183. "/BoxF { stroke [] 0 setdash exch hpt sub exch vpt add M\n",
  184. "  0 vpt2 neg V  hpt2 0 V  0 vpt2 V\n",
  185. "  hpt2 neg 0 V  closepath fill } def\n",
  186.  
  187. /* div added filled triangle */
  188. /* Triangle Up, Filled */
  189. "/TriUF { stroke [] 0 setdash vpt 1.12 mul add M\n",
  190. "  hpt neg vpt -1.62 mul V\n",
  191. "  hpt 2 mul 0 V\n",
  192. "  hpt neg vpt 1.62 mul V closepath fill } def\n",
  193.  
  194. /* Matt Heffron: added a few more types */
  195. /* Triangle Down */
  196. "/TriD { stroke [] 0 setdash 2 copy vpt 1.12 mul sub M\n", 
  197. "  hpt neg vpt 1.62 mul V\n",
  198. "  hpt 2 mul 0 V\n",
  199. "  hpt neg vpt -1.62 mul V closepath stroke\n",
  200. "  Pnt  } def\n",
  201.  
  202. /* Triangle Down, Filled*/
  203. "/TriDF { stroke [] 0 setdash vpt 1.12 mul sub M\n",
  204. "  hpt neg vpt 1.62 mul V\n",
  205. "  hpt 2 mul 0 V\n",
  206. "  hpt neg vpt -1.62 mul V closepath fill} def\n",
  207.  
  208. /* Diamond, Filled */
  209. "/DiaF { stroke [] 0 setdash vpt add M\n",
  210. "  hpt neg vpt neg V hpt vpt neg V\n",
  211. "  hpt vpt V hpt neg vpt V closepath fill } def\n",
  212.  
  213. /* Pentagon */
  214. "/Pent { stroke [] 0 setdash 2 copy gsave\n",
  215. "  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat\n",
  216. "  closepath stroke grestore Pnt } def\n",
  217.  
  218. /* Pentagon, Filled */
  219. "/PentF { stroke [] 0 setdash gsave\n",
  220. "  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat\n",
  221. "  closepath fill grestore } def\n",
  222.  
  223. /* Circle */
  224. "/Circle { stroke [] 0 setdash 2 copy\n",
  225. "  hpt 0 360 arc stroke Pnt } def\n",
  226.  
  227. /* Circle,Filled */
  228. "/CircleF { stroke [] 0 setdash hpt 0 360 arc fill } def\n",
  229. /* 16 differently filled circles */
  230. "/C0 { BL [] 0 setdash 2 copy moveto vpt 90 450  arc } bind def\n",
  231. "/C1 { BL [] 0 setdash 2 copy        moveto\n",
  232. "       2 copy  vpt 0 90 arc closepath fill\n",
  233. "               vpt 0 360 arc closepath } bind def\n",
  234. "/C2 { BL [] 0 setdash 2 copy moveto\n",
  235. "       2 copy  vpt 90 180 arc closepath fill\n",
  236. "               vpt 0 360 arc closepath } bind def\n",
  237. "/C3 { BL [] 0 setdash 2 copy moveto\n",
  238. "       2 copy  vpt 0 180 arc closepath fill\n",
  239. "               vpt 0 360 arc closepath } bind def\n",
  240. "/C4 { BL [] 0 setdash 2 copy moveto\n",
  241. "       2 copy  vpt 180 270 arc closepath fill\n",
  242. "               vpt 0 360 arc closepath } bind def\n",
  243. "/C5 { BL [] 0 setdash 2 copy moveto\n",
  244. "       2 copy  vpt 0 90 arc\n",
  245. "       2 copy moveto\n",
  246. "       2 copy  vpt 180 270 arc closepath fill\n",
  247. "               vpt 0 360 arc } bind def\n",
  248. "/C6 { BL [] 0 setdash 2 copy moveto\n",
  249. "      2 copy  vpt 90 270 arc closepath fill\n",
  250. "              vpt 0 360 arc closepath } bind def\n",
  251. "/C7 { BL [] 0 setdash 2 copy moveto\n",
  252. "      2 copy  vpt 0 270 arc closepath fill\n",
  253. "              vpt 0 360 arc closepath } bind def\n",
  254. "/C8 { BL [] 0 setdash 2 copy moveto\n",
  255. "      2 copy vpt 270 360 arc closepath fill\n",
  256. "              vpt 0 360 arc closepath } bind def\n",
  257. "/C9 { BL [] 0 setdash 2 copy moveto\n",
  258. "      2 copy  vpt 270 450 arc closepath fill\n",
  259. "              vpt 0 360 arc closepath } bind def\n",
  260. "/C10 { BL [] 0 setdash 2 copy 2 copy moveto vpt 270 360 arc closepath fill\n",
  261. "       2 copy moveto\n",
  262. "       2 copy vpt 90 180 arc closepath fill\n",
  263. "               vpt 0 360 arc closepath } bind def\n",
  264. "/C11 { BL [] 0 setdash 2 copy moveto\n",
  265. "       2 copy  vpt 0 90 arc closepath fill\n",
  266. "       2 copy moveto\n",
  267. "       2 copy  vpt 180 360 arc closepath fill\n",
  268. "               vpt 0 360 arc closepath } bind def\n",
  269. "/C12 { BL [] 0 setdash 2 copy moveto\n",
  270. "       2 copy  vpt 180 360 arc closepath fill\n",
  271. "               vpt 0 360 arc closepath } bind def\n",
  272. "/C13 { BL [] 0 setdash  2 copy moveto\n",
  273. "       2 copy  vpt 0 90 arc closepath fill\n",
  274. "       2 copy moveto\n",
  275. "       2 copy  vpt 180 360 arc closepath fill\n",
  276. "               vpt 0 360 arc closepath } bind def\n",
  277. "/C14 { BL [] 0 setdash 2 copy moveto\n",
  278. "       2 copy  vpt 90 360 arc closepath fill\n",
  279. "               vpt 0 360 arc } bind def\n",
  280. "/C15 { BL [] 0 setdash 2 copy vpt 0 360 arc closepath fill\n",
  281. "               vpt 0 360 arc closepath } bind def\n",
  282.  
  283. /* Auxiliary definitions for rectangles */
  284.  
  285. "/Rec   { newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto\n",
  286. "       neg 0 rlineto closepath } bind def\n",
  287. "/Square { dup Rec } bind def\n",
  288. "/Bsquare { vpt sub exch vpt sub exch vpt2 Square } bind def\n",
  289.  
  290. /* 16 differently filled squares */
  291.  
  292. "/S0 { BL [] 0 setdash 2 copy moveto 0 vpt rlineto BL Bsquare } bind def\n",
  293. "/S1 { BL [] 0 setdash 2 copy vpt Square fill Bsquare } bind def\n",
  294. "/S2 { BL [] 0 setdash 2 copy exch vpt sub exch vpt Square fill Bsquare } bind def\n",
  295. "/S3 { BL [] 0 setdash 2 copy exch vpt sub exch vpt2 vpt Rec fill Bsquare } bind def\n",
  296. "/S4 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt Square fill Bsquare } bind def\n",
  297. "/S5 { BL [] 0 setdash 2 copy 2 copy vpt Square fill\n",
  298. "       exch vpt sub exch vpt sub vpt Square fill Bsquare } bind def\n",
  299. "/S6 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill Bsquare } bind def\n",
  300. "/S7 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill\n",
  301. "       2 copy vpt Square fill\n",
  302. "       Bsquare } bind def\n",
  303. "/S8 { BL [] 0 setdash 2 copy vpt sub vpt Square fill Bsquare } bind def\n",
  304. "/S9 { BL [] 0 setdash 2 copy vpt sub vpt vpt2 Rec fill Bsquare } bind def\n",
  305. "/S10 { BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt Square fill\n",
  306. "       Bsquare } bind def\n",
  307. "/S11 { 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt2 vpt Rec fill\n",
  308. "       Bsquare } bind def\n",
  309. "/S12 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill Bsquare } bind def\n",
  310. "/S13 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill\n",
  311. "       2 copy vpt Square fill Bsquare } bind def\n",
  312. "/S14 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill\n",
  313. "       2 copy exch vpt sub exch vpt Square fill Bsquare } bind def\n",
  314. "/S15 { BL [] 0 setdash 2 copy Bsquare fill Bsquare } bind def\n",
  315.  
  316. /* 16 different diamonds (actually just rotated squares) */
  317.  
  318. "/D0 { gsave translate 45 rotate 0 0 Box stroke grestore } bind def\n",
  319. "/D1 { gsave translate 45 rotate 0 0 S1 stroke grestore } bind def\n",
  320. "/D2 { gsave translate 45 rotate 0 0 S2 stroke grestore } bind def\n",
  321. "/D3 { gsave translate 45 rotate 0 0 S3 stroke grestore } bind def\n",
  322. "/D4 { gsave translate 45 rotate 0 0 S4 stroke grestore } bind def\n",
  323. "/D5 { gsave translate 45 rotate 0 0 S5 stroke grestore } bind def\n",
  324. "/D6 { gsave translate 45 rotate 0 0 S6 stroke grestore } bind def\n",
  325. "/D7 { gsave translate 45 rotate 0 0 S7 stroke grestore } bind def\n",
  326. "/D8 { gsave translate 45 rotate 0 0 S8 stroke grestore } bind def\n",
  327. "/D9 { gsave translate 45 rotate 0 0 S9 stroke grestore } bind def\n",
  328. "/D10 { gsave translate 45 rotate 0 0 S10 stroke grestore } bind def\n",
  329. "/D11 { gsave translate 45 rotate 0 0 S11 stroke grestore } bind def\n",
  330. "/D12 { gsave translate 45 rotate 0 0 S12 stroke grestore } bind def\n",
  331. "/D13 { gsave translate 45 rotate 0 0 S13 stroke grestore } bind def\n",
  332. "/D14 { gsave translate 45 rotate 0 0 S14 stroke grestore } bind def\n",
  333. "/D15 { gsave translate 45 rotate 0 0 S15 stroke grestore } bind def\n",
  334.  
  335. NULL
  336. };
  337.  
  338. static char GPFAR * GPFAR ENHPS_header[] = {
  339. /* For MFshow and MFwidth the tos is an array with the string and font info:  */
  340. /*    [<fontname (a string)> <fontsize> <vertical offset> <width significant?> <printed?> <text string>]  */
  341.  
  342. "/MFshow {{dup dup 0 get findfont exch 1 get scalefont setfont\n",
  343. "     [ currentpoint ] exch dup 2 get 0 exch rmoveto dup dup 5 get exch 4 get\n",
  344. "     {show} {stringwidth pop 0 rmoveto}ifelse dup 3 get\n",
  345. "     {2 get neg 0 exch rmoveto pop} {pop aload pop moveto}ifelse} forall} bind def\n",
  346. "/MFwidth {0 exch {dup 3 get{dup dup 0 get findfont exch 1 get scalefont setfont\n",
  347. "      5 get stringwidth pop add}\n",
  348. "    {pop} ifelse} forall} bind def\n",
  349.  
  350. /* flush left show */
  351. "/MLshow { currentpoint stroke M\n",
  352. "  0 exch R MFshow } bind def\n", 
  353.  
  354. /* flush right show */
  355. "/MRshow { currentpoint stroke M\n",
  356. "  exch dup MFwidth neg 3 -1 roll R MFshow } def\n", 
  357.  
  358. /* centred show */
  359. "/MCshow { currentpoint stroke M\n",
  360. "  exch dup MFwidth -2 div 3 -1 roll R MFshow } def\n", 
  361. NULL
  362. };
  363.  
  364. /* added to enhpost by Matt Heffron <heffron@falstaff.css.beckman.com> */
  365. /* moved to post.trm by drd */
  366.  
  367. static struct PS_FontName {
  368.     char *name;
  369.     struct PS_FontName *next;
  370. } *PS_DocFonts = NULL;
  371.  
  372. /* given a font, look in store to see if it is there already
  373.  * if so, return NULL. If not, reencode it if allowed to, otherwise
  374.  * return an appropriate re-encode string
  375.  */
  376.  
  377. TERM_PUBLIC char *PS_RememberFont(fname, can_reencode)
  378. char *fname;
  379. int can_reencode;
  380. {
  381.     struct PS_FontName *fnp;
  382.     char *recode = NULL;
  383.  
  384.    for (fnp=PS_DocFonts; fnp ; fnp = fnp->next)
  385.         if (strcmp(fnp->name, fname)==0)
  386.             return NULL;
  387.  
  388.     /* we did not find the name */
  389.    
  390.    fnp = (struct PS_FontName *)alloc(sizeof(struct PS_FontName), "PostScript Font record");
  391.    fnp->name = alloc(1+strlen(fname), "PostScript Font name");
  392.    strcpy(fnp->name, fname);
  393.    fnp->next = PS_DocFonts;
  394.    PS_DocFonts = fnp;
  395.  
  396.     switch(encoding)
  397.     {
  398.         case ENCODING_ISO_8859_1:
  399.             recode = "reencodeISO def\n";
  400.             break;
  401.         case ENCODING_CP_437:
  402.             recode = "reencodeCP437 def\n";
  403.             break;
  404.         case ENCODING_CP_850 : 
  405.             recode = "reencodeCP850 def\n";
  406.             break;
  407.     }
  408.  
  409.     if (can_reencode && recode)
  410.     {    fprintf(outfile,"/%s %s",fname, recode);
  411.         return NULL;
  412.     }
  413.     else
  414.         return recode;
  415. }
  416.  
  417. static int PS_pen_x, PS_pen_y;
  418. static int PS_taken;
  419. static int PS_linetype_last;
  420. static TBOOLEAN PS_relative_ok;
  421.  
  422. TERM_PUBLIC void PS_options()
  423. {
  424.     if (!END_OF_COMMAND) {
  425.         if (almost_equals(c_token,"p$ortrait")) {
  426.             ps_portrait=TRUE;
  427.              ps_eps=FALSE;
  428.             c_token++;
  429.         }
  430.         else if (almost_equals(c_token,"l$andscape")) {
  431.             ps_portrait=FALSE;
  432.              ps_eps=FALSE;
  433.             c_token++;
  434.         }
  435.          else if (almost_equals(c_token,"ep$sf")) {
  436.              ps_portrait=TRUE;
  437.              ps_eps = TRUE;
  438.              c_token++;
  439.          }
  440.         else if (almost_equals(c_token,"d$efault")) {
  441.             ps_portrait=FALSE;
  442.              ps_eps=FALSE;
  443.             ps_color=FALSE;
  444.             ps_solid=FALSE;
  445.             ps_duplex_option=FALSE;
  446.             strcpy(ps_font,"Helvetica");
  447.             ps_fontsize = 14;
  448.             term->v_char = (unsigned int)(ps_fontsize*PS_SC);
  449.             term->h_char = (unsigned int)(ps_fontsize*PS_SC*6/10);
  450.             term->put_text = PS_put_text;
  451.             c_token++;
  452.         }
  453.     }
  454.  
  455.     if (almost_equals(c_token, "enh$anced")) {
  456.         term->put_text = ENHPS_put_text;
  457.         ++c_token;
  458.     } else if (almost_equals(c_token, "noenh$anced")) {
  459.         term->put_text = PS_put_text;
  460.         ++c_token;
  461.     }
  462.  
  463.     if (!END_OF_COMMAND) {
  464.         if (almost_equals(c_token,"m$onochrome")) {
  465.             ps_color=FALSE;
  466.             c_token++;
  467.         }
  468.         else if (almost_equals(c_token,"c$olor")) {
  469.             ps_color=TRUE;
  470.             c_token++;
  471.         }
  472.     }
  473.  
  474.     if (!END_OF_COMMAND) {
  475.         if (almost_equals(c_token,"so$lid")) {
  476.             ps_solid=TRUE;
  477.             c_token++;
  478.         }
  479.         else if (almost_equals(c_token,"da$shed")) {
  480.             ps_solid=FALSE;
  481.             c_token++;
  482.         }
  483.     }
  484.  
  485.     if (!END_OF_COMMAND) {
  486.         if (almost_equals(c_token,"si$mplex")) {
  487.             ps_duplex_state  = FALSE;
  488.             ps_duplex_option = TRUE;
  489.             c_token++;
  490.         }
  491.         else if (almost_equals(c_token,"du$plex")) {
  492.             ps_duplex_state  = TRUE;
  493.             ps_duplex_option = TRUE;
  494.             c_token++;
  495.         }
  496.         else if (almost_equals(c_token,"defaultp$lex")) {
  497.             ps_duplex_option = FALSE;
  498.             c_token++;
  499.         }
  500.     }
  501.  
  502.     if (!END_OF_COMMAND && isstring(c_token)) {
  503.         quote_str(ps_font,c_token, MAX_ID_LEN);
  504.         c_token++;
  505.     }
  506.  
  507.     if (!END_OF_COMMAND) {
  508.         /* We have font size specified */
  509.         struct value a;
  510.         ps_fontsize = (int)real(const_express(&a));
  511.         term->v_char = (unsigned int)(ps_fontsize*PS_SC);
  512.         term->h_char = (unsigned int)(ps_fontsize*PS_SC*6/10);
  513.     }
  514.  
  515.     sprintf(default_font,"%s,%d",ps_font,ps_fontsize);
  516.     /* default_font holds the font and size set at 'set term' */
  517.     /* Entry font added by DJL */
  518.     sprintf(term_options,"%s %senhanced %s %s %s \"%s\" %d",
  519.         ps_eps ? "eps" : (ps_portrait ? "portrait" : "landscape"),
  520.       term->put_text == ENHPS_put_text ? "" : "no",
  521.         ps_color ? "color" : "monochrome",
  522.         ps_solid ? "solid" : "dashed",
  523.         ps_duplex_option ? (ps_duplex_state ? "duplex" : "simplex")
  524.                                     : "defaultplex",
  525.         ps_font,ps_fontsize);
  526. }
  527.  
  528. /* store settings passed to common_init() for use in PS_graphics()
  529.  * ps_eps, ps_portrait, etc are reserved for storing the term options
  530.  */
  531. static int ps_common_encap;
  532. static int ps_common_portrait;
  533. static int ps_common_uses_fonts;
  534. static unsigned int ps_common_xoff, ps_common_yoff;
  535.  
  536.  
  537. TERM_PUBLIC void PS_common_init(encap, portrait, uses_fonts, xoff, yoff, bb_xmin, bb_ymin, bb_xmax, bb_ymax, dict)
  538. int encap; /* encapsulated or not - 1 for pslatex */
  539. int portrait; /* 1 for pslatex */
  540. int uses_fonts; /* 0 for ps(la)tex */
  541. unsigned int xoff, yoff; /* how much to translate by */
  542. unsigned int bb_xmin, bb_ymin, bb_xmax, bb_ymax; /* bounding box */
  543. char **dict; /* extra entries for the dictionary */
  544. {
  545. static char GPFAR psi1[] = "%%%%Creator: gnuplot\n\
  546. %%%%DocumentFonts: %s\n";
  547. static char GPFAR psi2[] = "%%%%EndComments\n\
  548. /gnudict 120 dict def\ngnudict begin\n\
  549. /Color %s def\n\
  550. /Solid %s def\n\
  551. /gnulinewidth %.3f def\n\
  552. /vshift %d def\n\
  553. /dl {%d mul} def\n\
  554. /hpt %.1f def\n\
  555. /vpt %.1f def\n";
  556. static char GPFAR *PS_iso_8859_1_encoding[] = {
  557. "/reencodeISO {\n",
  558. "dup dup findfont dup length dict begin\n",
  559. "{ 1 index /FID ne { def }{ pop pop } ifelse } forall\n",
  560. "/Encoding ISOLatin1Encoding def\n",
  561. "currentdict end definefont\n",
  562. "} def\n",
  563. "/ISOLatin1Encoding [\n",
  564. "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n",
  565. "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n",
  566. "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n",
  567. "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n",
  568. "/space/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright\n",
  569. "/parenleft/parenright/asterisk/plus/comma/minus/period/slash\n",
  570. "/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon\n",
  571. "/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N\n",
  572. "/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright\n",
  573. "/asciicircum/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m\n",
  574. "/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/asciitilde\n",
  575. "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n",
  576. "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n",
  577. "/.notdef/dotlessi/grave/acute/circumflex/tilde/macron/breve\n",
  578. "/dotaccent/dieresis/.notdef/ring/cedilla/.notdef/hungarumlaut\n",
  579. "/ogonek/caron/space/exclamdown/cent/sterling/currency/yen/brokenbar\n",
  580. "/section/dieresis/copyright/ordfeminine/guillemotleft/logicalnot\n",
  581. "/hyphen/registered/macron/degree/plusminus/twosuperior/threesuperior\n",
  582. "/acute/mu/paragraph/periodcentered/cedilla/onesuperior/ordmasculine\n",
  583. "/guillemotright/onequarter/onehalf/threequarters/questiondown\n",
  584. "/Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla\n",
  585. "/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex\n",
  586. "/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis\n",
  587. "/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute\n",
  588. "/Thorn/germandbls/agrave/aacute/acircumflex/atilde/adieresis\n",
  589. "/aring/ae/ccedilla/egrave/eacute/ecircumflex/edieresis/igrave\n",
  590. "/iacute/icircumflex/idieresis/eth/ntilde/ograve/oacute/ocircumflex\n",
  591. "/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex/udieresis\n",
  592. "/yacute/thorn/ydieresis\n",
  593. "] def\n",
  594. NULL };
  595.  
  596. /*   encoding for code page 437                                            */
  597. /*                                                                         */
  598. /*   version 1.0:  - Mainly letters are mapped. The following positions    */
  599. /*   (JFi)           are left blank (undefined):                           */
  600. /*                   -- first 32 positions,                                */
  601. /*                   -- frame characters,                                  */
  602. /*                   -- greek characters,                                  */
  603. /*                   -- some more special characters.                      */
  604. /*                                                                         */
  605. /*   version 1.1:  - added some more special characters                    */
  606. /*                                                                         */
  607. static char GPFAR *PS_cp_437_encoding[] = {
  608. "/reencodeCP437 {\n",
  609. "dup dup findfont dup length dict begin\n",
  610. "{ 1 index /FID ne { def }{ pop pop } ifelse } forall\n",
  611. "/Encoding CP437Encoding def\n",
  612. "currentdict end definefont\n",
  613. "} def\n",
  614. "/CP437Encoding [\n",
  615. "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n",
  616. "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n",
  617. "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n",
  618. "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n",
  619. "/space/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright\n",
  620. "/parenleft/parenright/asterisk/plus/comma/minus/period/slash\n",
  621. "/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon\n",
  622. "/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N\n",
  623. "/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright\n",
  624. "/asciicircum/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m\n",
  625. "/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/asciitilde/.notdef\n",
  626. "/Ccedilla/udieresis/eacute/acircumflex/adieresis/agrave/aring/ccedilla\n",
  627. "/ecircumflex/edieresis/egrave/idieresis/icircumflex/igrave/Adieresis/Aring\n",
  628. "/Eacute/ae/AE/ocircumflex/odieresis/ograve/ucircumflex/ugrave\n",
  629. "/ydieresis/Odieresis/Udieresis/cent/sterling/yen/.notdef/florin\n",
  630. "/aacute/iacute/oacute/uacute/ntilde/Ntilde/ordfeminine/ordmasculine\n",
  631. "/questiondown/.notdef/logicalnot/onehalf/onequarter/exclamdown/guillemotleft/guillemotright\n",
  632. "/space/space/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n",
  633. "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n",
  634. "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n",
  635. "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n",
  636. "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n",
  637. "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n",
  638. "/.notdef/germandbls/.notdef/.notdef/.notdef/.notdef/mu/.notdef\n",
  639. "/.notdef/.notdef/.notdef/.notdef/infinity/.notdef/.notdef/.notdef\n",
  640. "/.notdef/plusminus/greaterequal/lessequal/.notdef/.notdef/divide/.notdef\n",
  641. "/degree/bullet/periodcentered/.notdef/nsuperior/twosuperior/.notdef\n",
  642. "] def\n",
  643. NULL };
  644.  
  645. /*   encoding for code page 850                                            */
  646. /*                                                                         */
  647. /*   version 1.0:  - Mainly letters are mapped. The following positions    */
  648. /*   (JFi)           are left blank (undefined):                           */
  649. /*                   -- first 32 positions,                                */
  650. /*                   -- frame characters,                                  */
  651. /*                   -- a few special characters.                          */
  652. /*                                                                         */
  653. static char GPFAR *PS_cp_850_encoding[] = {
  654. "/reencodeCP850 {\n",
  655. "dup dup findfont dup length dict begin\n",
  656. "{ 1 index /FID ne { def }{ pop pop } ifelse } forall\n",
  657. "/Encoding CP850Encoding def\n",
  658. "currentdict end definefont\n",
  659. "} def\n",
  660. "/CP850Encoding [\n",
  661. "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n",
  662. "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n",
  663. "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n",
  664. "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n",
  665. "/space/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright\n",
  666. "/parenleft/parenright/asterisk/plus/comma/minus/period/slash\n",
  667. "/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon\n",
  668. "/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N\n",
  669. "/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright\n",
  670. "/asciicircum/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m\n",
  671. "/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/asciitilde/.notdef\n",
  672. "/Ccedilla/udieresis/eacute/acircumflex/adieresis/agrave/aring/ccedilla\n",
  673. "/ecircumflex/edieresis/egrave/idieresis/icircumflex/igrave/Adieresis/Aring\n",
  674. "/Eacute/ae/AE/ocircumflex/odieresis/ograve/ucircumflex/ugrave\n",
  675. "/ydieresis/Odieresis/Udieresis/oslash/sterling/Oslash/multiply/florin\n",
  676. "/aacute/iacute/oacute/uacute/ntilde/Ntilde/ordfeminine/ordmasculine\n",
  677. "/questiondown/registered/logicalnot/onehalf/onequarter/exclamdown/guillemotleft/guillemotright\n",
  678. "/space/space/.notdef/.notdef/.notdef/Aacute/Acircumflex/Agrave\n",
  679. "/.notdef/.notdef/.notdef/.notdef/.notdef/cent/yen/.notdef\n",
  680. "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/atilde/Atilde\n",
  681. "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/currency\n",
  682. "/eth/Eth/Ecircumflex/Edieresis/Egrave/dotlessi/Iacute/Icircumflex\n",
  683. "/Idieresis/.notdef/.notdef/.notdef/.notdef/brokenbar/Igrave/.notdef\n",
  684. "/Oacute/germandbls/Ocircumflex/Ograve/otilde/Otilde/mu/thorn\n",
  685. "/Thorn/Uacute/Ucircumflex/Ugrave/yacute/Yacute/macron/acute\n",
  686. "/hyphen/plusminus/equal/threequarters/paragraph/section/divide/.notdef\n",
  687. "/degree/.notdef/periodcentered/onesuperior/threesuperior/twosuperior/.notdef\n",
  688. "] def\n",
  689. NULL };
  690.  
  691.     struct termentry *t = term;
  692.     int i;
  693.  
  694.     ps_common_encap = encap; /* store for later */
  695.     ps_common_portrait = portrait; /* store for later */
  696.     ps_common_uses_fonts = uses_fonts;
  697.     ps_common_xoff = xoff;
  698.     ps_common_yoff = yoff;
  699.  
  700.     ps_page = 0;
  701.  
  702.     if (!encap)
  703.         fprintf(outfile,"%%!PS-Adobe-2.0\n");
  704.     else
  705.         fprintf(outfile,"%%!PS-Adobe-2.0 EPSF-2.0\n");
  706.  
  707.     fprintf(outfile, "%%%%Title: %s\n", outstr );             /*  JFi  */
  708.     fprintf(outfile, psi1, uses_fonts ? "(atend)" : "");
  709.  
  710.     fprintf(outfile,"%%%%BoundingBox: %d %d %d %d\n", xoff + bb_xmin, yoff + bb_ymin, xoff + bb_xmax, yoff + bb_ymax);
  711.  
  712.     if (!encap)
  713.         fprintf(outfile,"%%%%Pages: (atend)\n");
  714.     fprintf(outfile, psi2,
  715.         ps_color ? "true" : "false",
  716.         ps_solid ? "true" : "false",
  717.         PS_LW,            /* line width */
  718.          (int)(t->v_char)/(-3),    /* shift for vertical centring */
  719.         PS_SC,            /* dash length */
  720.         pointsize*PS_HTIC/2.0,        /* half point width */
  721.         pointsize*PS_VTIC/2.0);        /* half point height */
  722.  
  723.     if (uses_fonts && (encoding == ENCODING_ISO_8859_1)) {
  724.         for (i=0; PS_iso_8859_1_encoding[i] != NULL; i++) {
  725.             fprintf(outfile,"%s",PS_iso_8859_1_encoding[i]);
  726.         }
  727.     }
  728.     if (uses_fonts && (encoding == ENCODING_CP_437)) {       /* JFi */
  729.         for (i=0; PS_cp_437_encoding[i] != NULL; i++) {
  730.             fprintf(outfile,"%s",PS_cp_437_encoding[i]);
  731.         }
  732.     }
  733.     if (uses_fonts && (encoding == ENCODING_CP_850)) {       /* JFi */
  734.         for (i=0; PS_cp_850_encoding[i] != NULL; i++) {
  735.             fprintf(outfile,"%s",PS_cp_850_encoding[i]);
  736.         }
  737.     }
  738. /*        Duplicate code! 
  739.           As long as only two code pages are implemented, that's not a big 
  740.           problem. Otherwise a small procedure might be beneficial.
  741. */
  742.  
  743.     for ( i=0; PS_header[i] != NULL; i++)
  744.         fprintf(outfile,"%s",PS_header[i]);
  745.     if (ps_duplex_option)
  746.         fprintf(outfile, "statusdict begin %s setduplexmode end\n",
  747.                 ps_duplex_state ? "true" : "false");
  748.     PS_RememberFont(ps_font, 1);
  749.  
  750.     if (dict)
  751.         while (*dict)
  752.             fputs(*(dict++), outfile);    
  753.  
  754.     fprintf(outfile,"end\n%%%%EndProlog\n");
  755. }
  756.  
  757. /* the init fn for the postscript driver */
  758. TERM_PUBLIC void PS_init()
  759. {
  760.     unsigned int xmin, ymin, xmax, ymax;
  761.  
  762.     if (ps_eps)
  763.     {
  764.         term->xmax = PS_XMAX;
  765.         term->ymax = PS_YMAX;
  766.         xmin = PS_XMAX * xoffset / (2*PS_SC);
  767.         xmax = PS_XMAX * (xsize + xoffset) / (2*PS_SC);
  768.         ymin = PS_YMAX * yoffset / (2*PS_SC);
  769.         ymax = PS_YMAX * (yoffset + ysize) / (2*PS_SC);
  770.     }
  771.     else if (ps_portrait)
  772.     {
  773.         term->xmax = PS_YMAX;
  774.         term->ymax = PS_XMAX;
  775.         xmin = PS_YMAX * xoffset / PS_SC;
  776.         xmax = PS_YMAX * (xsize + xoffset) / PS_SC;
  777.         ymin = PS_XMAX * yoffset / PS_SC;
  778.         ymax = PS_XMAX * (ysize + yoffset) / PS_SC;
  779.     }
  780.     else
  781.     {
  782.         term->xmax = PS_XMAX;
  783.         term->ymax = PS_YMAX;
  784.         ymin = PS_XMAX * xoffset / PS_SC;
  785.         ymax = PS_XMAX * (xsize+xoffset) / PS_SC;
  786.         xmin = PS_YMAX * (1-ysize-yoffset) / PS_SC;
  787.         xmax = PS_YMAX * (1-yoffset) / PS_SC;
  788.     }
  789.     
  790.     PS_common_init(ps_eps, ps_portrait, 1, PS_XOFF, PS_YOFF,
  791.        xmin, ymin, xmax, ymax,
  792.        (term->put_text == ENHPS_put_text) ? ENHPS_header : NULL);
  793. }
  794.  
  795.  
  796. TERM_PUBLIC void PS_graphics()
  797. {
  798. static char GPFAR psg1[] = "0 setgray\nnewpath\n";
  799. struct termentry *t = term;
  800.     ps_page++;
  801.     if (!ps_common_encap)
  802.         fprintf(outfile,"%%%%Page: %d %d\n",ps_page,ps_page);
  803.     fprintf(outfile,"gnudict begin\ngsave\n");
  804.     fprintf(outfile,"%d %d translate\n",ps_common_xoff, ps_common_yoff);
  805.     fprintf(outfile,"%.3f %.3f scale\n", (ps_eps ? 0.5 : 1.0)/PS_SC,
  806.                                          (ps_eps ? 0.5 : 1.0)/PS_SC);
  807.     if (!ps_common_portrait) {
  808.         fprintf(outfile,"90 rotate\n0 %d translate\n", (int)(-PS_YMAX));
  809.     }
  810.     fprintf(outfile, psg1);
  811.     if (ps_common_uses_fonts)
  812.         fprintf(outfile, "(%s) findfont %d scalefont setfont\n", ps_font, (t->v_char) );
  813.     ps_path_count = 0;
  814.     PS_relative_ok = FALSE;
  815.     PS_pen_x = PS_pen_y = -4000;
  816.     PS_taken = 0;
  817.     PS_linetype_last = -1;
  818. }
  819.  
  820.  
  821. TERM_PUBLIC void PS_text()
  822. {
  823.     ps_path_count = 0;
  824.     fprintf(outfile,"stroke\ngrestore\nend\nshowpage\n");
  825.     /* fprintf(stderr,"taken %d times\n",PS_taken); */
  826.     /* informational:  tells how many times it was "cheaper"
  827.        to do a relative moveto or lineto rather than an
  828.        absolute one */
  829. }
  830.  
  831.  
  832. TERM_PUBLIC void PS_reset()
  833. {
  834.     fprintf(outfile,"%%%%Trailer\n");
  835.  
  836. /*      I think the following commands should be executed 
  837.         `if (ps_common_uses_fonts)`. So I changed the next line. 
  838.         Please see "PS_RememberFont", too.                       */  /* JFi */
  839.  
  840. /*    if (!ps_common_uses_fonts) {  */                             /* JFi */
  841.     if (ps_common_uses_fonts) {
  842.         fprintf(outfile,"%%%%DocumentFonts: ");
  843.         while (PS_DocFonts) {
  844.             struct PS_FontName *fnp;
  845.             fnp = PS_DocFonts->next;
  846.             fprintf(outfile, "%s%s", PS_DocFonts->name, fnp ? ", " : "\n");
  847.             free(PS_DocFonts->name);
  848.             free(PS_DocFonts);
  849.             PS_DocFonts=fnp;
  850.         }
  851.     }
  852.     if (!ps_common_encap)
  853.         fprintf(outfile,"%%%%Pages: %d\n",ps_page);
  854. }
  855.  
  856.  
  857. TERM_PUBLIC void PS_linetype(linetype)
  858. int linetype;
  859. {
  860.     linetype = (linetype % 9) + 2;
  861.     if (linetype < 0) linetype = 0;
  862.     PS_relative_ok = FALSE;
  863.     if (PS_linetype_last == linetype) return;
  864.     PS_linetype_last = linetype;
  865.     fprintf(outfile,"LT%c\n", "ba012345678"[linetype]);
  866.     ps_path_count = 0;
  867. }
  868.  
  869.  
  870. TERM_PUBLIC void PS_move(x,y)
  871. unsigned int x,y;
  872. {
  873.     int dx, dy;
  874.     char abso[20],rel[20];
  875.     dx = x - PS_pen_x;
  876.     dy = y - PS_pen_y;
  877.     /* can't cancel all null moves--need a move after stroke'ing */
  878.     if (dx==0 && dy==0 && PS_relative_ok)
  879.         return;
  880.     sprintf(abso, "%d %d M\n", x, y);
  881.     sprintf(rel, "%d %d R\n", dx, dy);
  882.     if (strlen(rel) < strlen(abso) && PS_relative_ok){
  883.         fputs(rel, outfile);
  884.         PS_taken++;
  885.     }else
  886.         fputs(abso, outfile);
  887.     PS_relative_ok = TRUE;
  888.     ps_path_count += 1;
  889.  
  890.     PS_pen_x = x;
  891.     PS_pen_y = y;
  892. }
  893.  
  894. TERM_PUBLIC void PS_vector(x,y)
  895. unsigned int x,y;
  896. {
  897.     int dx, dy;
  898.     char abso[20],rel[20];
  899.     dx = x - PS_pen_x;
  900.     dy = y - PS_pen_y;
  901.     if (dx==0 && dy==0) return;
  902.     sprintf(abso, "%d %d L\n", x, y);
  903.     sprintf(rel, "%d %d V\n", dx, dy);
  904.     if (strlen(rel) < strlen(abso) && PS_relative_ok){
  905.         fputs(rel, outfile);
  906.         PS_taken++;
  907.     }else
  908.         fputs(abso, outfile);
  909.     PS_relative_ok = TRUE;
  910.     ps_path_count += 1;
  911.     PS_pen_x = x;
  912.     PS_pen_y = y;
  913.     if (ps_path_count >= 400) {
  914.         fprintf(outfile,"currentpoint stroke M\n");
  915.         ps_path_count = 0;
  916.     }
  917. }
  918.  
  919.  
  920. TERM_PUBLIC void PS_put_text(x,y,str)
  921. unsigned int x, y;
  922. char *str;
  923. {
  924. char ch;
  925.     if (!strlen(str)) return;
  926.     PS_move(x,y);
  927.     if (ps_ang != 0)
  928.         fprintf(outfile,"currentpoint gsave translate %d rotate 0 0 M\n"
  929.             ,ps_ang*90);
  930.     putc('(',outfile);
  931.     ch = *str++;
  932.     while(ch!='\0') {
  933.         if ( (ch=='(') || (ch==')') || (ch=='\\') )
  934.             putc('\\',outfile);
  935.         putc(ch,outfile);
  936.         ch = *str++;
  937.     }
  938.     switch(ps_justify) {
  939.         case LEFT : fprintf(outfile,") Lshow\n");
  940.             break;
  941.         case CENTRE : fprintf(outfile,") Cshow\n");
  942.             break;
  943.         case RIGHT : fprintf(outfile,") Rshow\n");
  944.             break;
  945.     }
  946.     if (ps_ang != 0)
  947.         fprintf(outfile,"grestore\n");
  948.     ps_path_count = 0;
  949.     PS_relative_ok = FALSE;
  950. }
  951.  
  952.  
  953. TERM_PUBLIC int PS_text_angle(ang)
  954. int ang;
  955. {
  956.     ps_ang=ang;
  957.     return TRUE;
  958. }
  959.  
  960.  
  961. TERM_PUBLIC int PS_justify_text(mode)
  962. enum JUSTIFY mode;
  963. {
  964.     ps_justify=mode;
  965.     return TRUE;
  966. }
  967.  
  968.  
  969. TERM_PUBLIC int PS_set_font(font)  /* Entry font added by DJL */
  970. char *font;
  971. {
  972. char name[32];
  973. int  size,sep;
  974.  
  975.         sep=strcspn(font,",");
  976.         strncpy(name,font,sep); name[sep]='\0';
  977.         size=ps_fontsize; sscanf (&(font[sep+1]),"%d",&size);
  978.         fprintf(outfile,"/%s findfont %d scalefont setfont\n",name,size*PS_SC);
  979.         PS_RememberFont(name,1 );
  980.         return TRUE;
  981. }
  982.  
  983.  
  984. /* postscript point routines */
  985.  
  986. TERM_PUBLIC void PS_set_pointsize(size)
  987. double size;
  988. {
  989.         fprintf(outfile, "/vpt %.1f def /hpt %.1f def /vpt2 vpt 2 mul def /hpt2 hpt 2 mul def\n",
  990.            pointsize*PS_VTIC*0.5, pointsize*PS_HTIC*0.5);
  991. }
  992.  
  993. TERM_PUBLIC void PS_point(x,y,number)
  994. unsigned int x,y;
  995. int number;
  996. {
  997. static char *pointFNS[] = {"Pnt",  "Pls",   "Crs",    "Star",
  998.                            "Box",  "BoxF",  "Circle", "CircleF",
  999.                            "TriU", "TriUF", "TriD",   "TriDF",
  1000.                            "Dia",  "DiaF",  "Pent",   "PentF",
  1001.                    "C0",   "C1",    "C2",     "C3",
  1002.                "C4",   "C5",    "C6",     "C7",
  1003.                      "C8",   "C9",    "C10",    "C11",
  1004.                "C12",  "C13",   "C14",    "C15",
  1005.                            "S0",   "S1",    "S2",     "S3",
  1006.                "S4",   "S5",    "S6",     "S7",
  1007.                            "S8",   "S9",    "S10",    "S11",
  1008.                "S12",  "S13",   "S14",    "S15",
  1009.                      "D0",   "D1",    "D2",     "D3",
  1010.                "D4",   "D5",    "D6",     "D7",
  1011.                "D8",   "D9",    "D10",    "D11",
  1012.                "D12",  "D13",   "D14",    "D15"
  1013. };
  1014.     if (number < 0)
  1015.         number = -1;        /* negative types are all 'dot' */
  1016.     else
  1017.         number %= sizeof(pointFNS)/sizeof(pointFNS[0]) -1;
  1018.     fprintf(outfile,"%d %d %s\n", x, y, pointFNS[number+1]);
  1019.  
  1020.     PS_relative_ok = 0;
  1021.     ps_path_count = 0;
  1022.     PS_linetype_last = -1; /* force next linetype change */
  1023. }
  1024.  
  1025.  
  1026.  
  1027.  
  1028. /* ENHPOST */
  1029.  
  1030.  
  1031. /* disable debugging info */
  1032. #define ENHPS_DEBUG(x) /* printf x; */
  1033.  
  1034. static TBOOLEAN ENHps_opened_string;  /* try to cut out empty ()'s */
  1035.  
  1036. /* used in determining height of processed text */
  1037.  
  1038. static float ENHps_max_height, ENHps_min_height;
  1039.  
  1040.  
  1041. /* process a bit of string, and return the last character used.
  1042.  * p is start of string
  1043.  * brace is TRUE to keep processing to }, FALSE for do one character
  1044.  * fontname & fontsize are obvious
  1045.  * base is the current baseline
  1046.  * widthflag is TRUE if the width of this should count,
  1047.  *              FALSE for zero width boxes
  1048.  * showflag is TRUE if this should be shown,
  1049.  *             FALSE if it should not be shown (like TeX \phantom)
  1050.  */
  1051.  
  1052. static char *ENHPS_recurse(p, brace, fontname, fontsize, base, widthflag, showflag)
  1053. char *p, *fontname;
  1054. TBOOLEAN brace, widthflag, showflag;
  1055. double fontsize, base;
  1056. {
  1057.  
  1058. /* close a postscript string if it has been opened */
  1059. #define ENHPS_FLUSH      \
  1060. {    if (ENHps_opened_string)  \
  1061.     {    fputs(")]\n", outfile);   \
  1062.         ENHps_opened_string = FALSE; \
  1063.     }                         \
  1064. }
  1065.  
  1066. #define ENHPS_OPEN    \
  1067. {    if (!ENHps_opened_string) \
  1068.     { fprintf(outfile, "[(%s) %.1f %.1f %s %s (",  \
  1069.           fontname, fontsize, base, \
  1070.            widthflag ? "true" : "false",  \
  1071.            showflag ? "true" : "false");  \
  1072.        ENHps_opened_string = TRUE; \
  1073.      }    \
  1074. }
  1075.  
  1076.     ENHPS_DEBUG(("RECURSE WITH [%p] %s, %d %s %.1f %.1f %d %d\n", p, p, brace, fontname, fontsize, base, widthflag, showflag))
  1077.  
  1078.     /* Start each recursion with a clean string */
  1079.     ENHPS_FLUSH
  1080.  
  1081.     if (base + fontsize > ENHps_max_height)
  1082.     {    ENHps_max_height = base + fontsize;
  1083.         ENHPS_DEBUG(("Setting max height to %.1f\n", ENHps_max_height));
  1084.     }
  1085.  
  1086.     if (base < ENHps_min_height)
  1087.     {    ENHps_min_height = base;
  1088.         ENHPS_DEBUG(("Setting min height to %.1f\n", ENHps_min_height));
  1089.     }
  1090.  
  1091.     for ( ; *p; ++p)
  1092.     {    float shift;
  1093.  
  1094.         switch (*p)
  1095.         {
  1096.             case '}'  :
  1097.                 /*{{{  deal with it*/
  1098.                 if (brace)
  1099.                     return (p);
  1100.                 
  1101.                 fprintf(stderr, "enhpost printer driver - spurious }\n");
  1102.                 break;
  1103.                 /*}}}*/
  1104.         
  1105.             case '_'  :
  1106.             case '^'  :
  1107.                 /*{{{  deal with super/sub script*/
  1108.                 
  1109.                 shift = (*p == '^') ? 0.5 : -0.3;
  1110.                 
  1111.                 ENHPS_FLUSH
  1112.                 
  1113.                 p = ENHPS_recurse(p+1, FALSE, fontname, fontsize*0.8, base+shift*fontsize, widthflag, showflag);
  1114.                 
  1115.                 break;
  1116.                 /*}}}*/
  1117.         
  1118.             case '{'  :
  1119.             {
  1120.                 char *savepos=NULL, save=0;
  1121.                 char *localfontname=fontname, ch;
  1122.                 int recode=1;
  1123.                 float f=fontsize;
  1124.  
  1125.                 /*{{{  recurse (possibly with a new font) */
  1126.                 
  1127.                 ENHPS_DEBUG(("Dealing with {\n"))
  1128.                 
  1129.                 if (*++p == '/')
  1130.                 {    /* then parse a fontname, optional fontsize */
  1131.                     while (*++p == ' ');
  1132.                     if (*p=='-')
  1133.                     {
  1134.                         recode=0;
  1135.                         while (*++p == ' ');
  1136.                     }
  1137.                     localfontname = p;
  1138.                     while ((ch = *p) > ' ' && ch != '=')
  1139.                         ++p;
  1140.                     save = *(savepos=p);
  1141.                     if (ch == '=')
  1142.                     {
  1143.                         *p++ = '\0';                
  1144.                         /*{{{  get optional font size*/
  1145.                         ENHPS_DEBUG(("Calling strtod(%s) ...", p))
  1146.                         f = (float)strtod(p, &p);
  1147.                         ENHPS_DEBUG(("Retured %.1f and %s\n", f, p))
  1148.                         
  1149.                         if (f)
  1150.                             f *= PS_SC;  /* remember the scaling */
  1151.                         else
  1152.                             f = fontsize;
  1153.                         
  1154.                         ENHPS_DEBUG(("Font size %.1f\n", f))
  1155.                         /*}}}*/
  1156.                     }
  1157.                     else
  1158.                     {
  1159.                         *p++ = '\0';
  1160.                         f = fontsize;
  1161.                     }                
  1162.                 
  1163.                     while (*p == ' ')
  1164.                         ++p;
  1165.                     if (*localfontname)
  1166.                     {
  1167.                         /* only allow RememberFont to re-encode it if no string active */
  1168.                         char *recodestring = PS_RememberFont(localfontname, recode && !ENHps_opened_string);
  1169.                         if (recode && recodestring)
  1170.                         {
  1171.                             ENHPS_FLUSH
  1172.                             fprintf(outfile, "/%s %s", localfontname, recodestring);
  1173.                         }
  1174.                     }
  1175.                     else
  1176.                         localfontname = fontname;
  1177.                 }
  1178.                 /*}}}*/
  1179.                 
  1180.                 ENHPS_DEBUG(("Before recursing, we are at [%p] %s\n", p, p))
  1181.                 
  1182.                 p = ENHPS_recurse(p, TRUE, localfontname, f, base, widthflag, showflag);
  1183.                 
  1184.                 ENHPS_DEBUG(("BACK WITH %s\n", p));
  1185.                 
  1186.                 ENHPS_FLUSH
  1187.  
  1188.                 if (savepos)
  1189.                     /* restore overwritten character */
  1190.                     *savepos = save;
  1191.         
  1192.                 break;
  1193.             }
  1194.                 
  1195.             case '@' :
  1196.                 /*{{{  phantom box - prints next 'char', then restores currentpoint */
  1197.     
  1198.                 ENHPS_FLUSH
  1199.     
  1200.                 p = ENHPS_recurse(++p, FALSE, fontname, fontsize, base, FALSE, showflag);
  1201.                     
  1202.                 break;
  1203.                 /*}}}*/
  1204.         
  1205.             case '&' :
  1206.                 /*{{{  character skip - skips space equal to length of character(s) */
  1207.     
  1208.                 ENHPS_FLUSH
  1209.     
  1210.                 p = ENHPS_recurse(++p, FALSE, fontname, fontsize, base, widthflag, FALSE);
  1211.                     
  1212.                 break;
  1213.                 /*}}}*/
  1214.         
  1215.             case '('  :
  1216.             case ')'  :
  1217.                 /*{{{  an escape and print it */
  1218.                 /* special cases */
  1219.                 ENHPS_OPEN
  1220.                 fputc('\\', outfile);
  1221.                 fputc(*p, outfile);
  1222.                 break;
  1223.                 /*}}}*/
  1224.         
  1225.             case '\\'  :
  1226.                 /*{{{  is it an escape */
  1227.                 /* special cases */
  1228.                 
  1229.                 if (p[1]=='\\' || p[1]=='(' || p[1]==')')
  1230.                 {
  1231.                     ENHPS_OPEN
  1232.                     fputc('\\', outfile);
  1233.                 }
  1234.                 else if (p[1] >= '0' && p[1] <= '7')
  1235.                 {
  1236.                     /* up to 3 octal digits */
  1237.                     ENHPS_OPEN
  1238.                     fputc('\\', outfile);
  1239.                     fputc(p[1], outfile);
  1240.                     ++p;
  1241.                     if (p[1] >= '0' && p[1] <= '7')
  1242.                     {
  1243.                         fputc(p[1], outfile);
  1244.                         ++p;
  1245.                         if (p[1] >= '0' && p[1] <= '7')
  1246.                         {
  1247.                             fputc(p[1], outfile);
  1248.                             ++p;
  1249.                         }
  1250.                     }
  1251.                     break;
  1252.                 }
  1253.     
  1254.                 ++p;
  1255.                 /* just go and print it (fall into the 'default' case) */
  1256.     
  1257.                 /*}}}*/
  1258.             default:
  1259.                 /*{{{  print it */
  1260.                 ENHPS_OPEN
  1261.     
  1262.                 fputc(*p, outfile);
  1263.     
  1264.             /*}}}*/
  1265.  
  1266.         }
  1267.  
  1268.         /* like TeX, we only do one character in a recursion, unless it's
  1269.          * in braces
  1270.          */
  1271.  
  1272.         if (!brace)
  1273.         {
  1274.             ENHPS_FLUSH
  1275.             return(p);  /* the ++p in the outer copy will increment us */
  1276.         }
  1277.     
  1278.     }
  1279.     ENHPS_FLUSH
  1280.     return p;
  1281.  
  1282.  
  1283. TERM_PUBLIC void ENHPS_put_text(x, y, str)
  1284. unsigned int x, y;
  1285. char *str;
  1286. {
  1287.     /* flush any pending graphics (all the XShow routines do this...) */
  1288.  
  1289.     if (!strlen(str))
  1290.         return;
  1291.  
  1292.     if (ps_path_count)
  1293.     {
  1294.         fputs(" stroke\n",outfile);
  1295.         ps_path_count=0;
  1296.         PS_relative_ok=FALSE;
  1297.     }
  1298.  
  1299.     PS_move(x,y);
  1300.  
  1301.     if (ps_ang != 0)
  1302.         fprintf(outfile,"currentpoint gsave translate %d rotate 0 0 moveto\n",
  1303.             ps_ang*90);
  1304.  
  1305.     fputs("[ ",outfile);
  1306.  
  1307.     /* set up the globals */
  1308.     
  1309.     ENHps_opened_string = FALSE;
  1310.     ENHps_max_height = -1000;
  1311.     ENHps_min_height = 1000;
  1312.  
  1313.     while (*(str = ENHPS_recurse(str, TRUE, ps_font,
  1314.                      (double)term->v_char,
  1315.                      0.0, TRUE, TRUE)));
  1316.  
  1317.     ENHps_max_height += ENHps_min_height;
  1318.         
  1319.     fprintf(outfile, "] %.1f ", -ENHps_max_height/3);
  1320.  
  1321.     switch(ps_justify)
  1322.     {
  1323.         case LEFT : fprintf(outfile, "MLshow\n");
  1324.             break;
  1325.         case CENTRE : fprintf(outfile, "MCshow\n");
  1326.             break;
  1327.         case RIGHT : fprintf(outfile, "MRshow\n");
  1328.             break;
  1329.     }
  1330.  
  1331.     if (ps_ang != 0)
  1332.         fputs("grestore\n", outfile);
  1333.     ps_path_count = 0;
  1334.     PS_relative_ok=FALSE;
  1335. }
  1336.  
  1337.  
  1338.  
  1339.  
  1340.  
  1341. #endif /* TERM_BODY */
  1342.  
  1343. #ifdef TERM_TABLE
  1344.  
  1345. TERM_TABLE_START(post_driver)
  1346.  
  1347.       "postscript",
  1348.       "PostScript graphics language [mode \042fontname\042 font_size]",
  1349.        PS_XMAX, PS_YMAX, PS_VCHAR, PS_HCHAR, 
  1350.        PS_VTIC, PS_HTIC, PS_options, PS_init, PS_reset, 
  1351.        PS_text, null_scale, PS_graphics, PS_move, PS_vector, 
  1352.        PS_linetype, PS_put_text, PS_text_angle, 
  1353.        PS_justify_text, PS_point, do_arrow, PS_set_font, PS_set_pointsize
  1354.  
  1355. TERM_TABLE_END(post_driver)
  1356.  
  1357. #undef LAST_TERM
  1358. #define LAST_TERM post_driver
  1359.  
  1360. #endif /* TERM_TABLE */
  1361.  
  1362. #endif /* TERM_PROTO_ONLY */
  1363.  
  1364.  
  1365.  
  1366. #ifdef TERM_HELP
  1367. START_HELP(post)
  1368. "1 postscript",
  1369. "?set terminal postscript",
  1370. "?postscript",
  1371. " Several options may be set in the PostScript driver.",
  1372. "",
  1373. " Syntax:",
  1374. "         set terminal postscript {<mode>} {<color>} {<dashed>} \\",
  1375. "                                 {\"<fontname>\"} {<fontsize>}",
  1376. "         set terminal postscript {<mode>} {<color>} {<dashed>} {<duplexing>} \\",
  1377. "                      {enhanced | noenhanced} {\"<fontname>\"} {<fontsize>}",
  1378. "",
  1379. " where <mode> is `landscape`, `portrait`, `eps` or `default`; <color> is",
  1380. " either `color` or `monochrome`; <dashed> is either `solid` or `dashed`;",
  1381. " <duplexing> is `defaultplex`, `simplex` or `duplex` (\"duplexing\" in",
  1382. " PostScript is the ability of the printer to print on both sides of the same",
  1383. " page---don't set this if your printer can't do it); `enhanced` activates the",
  1384. " \"Enhanced PostScript\" features (sub- and super-scripts and mixed fonts);",
  1385. " `\"<fontname>\"` is the name of a valid PostScript font; and `<fontsize>` is",
  1386. " the size of the font in PostScript points.  Selecting `default` sets all",
  1387. " options to the defaults: `landscape`, `monochrome`, `dashed`, `defaultplex`,",
  1388. " `noenhanced`, \"Helvetica\", and 14pt.  Default size of a PostScript plot is 10",
  1389. " inches wide and 7 inches high.",
  1390. "",
  1391. " EPS (Encapsulated PostScript) output is just regular PostScript with some",
  1392. " lines added which allow the file to be imported into a variety of other",
  1393. " applications.  (The added lines are PostScript comment lines, so the file may",
  1394. " still be printed by itself.)  To get EPS output, use the `eps` mode and make",
  1395. " only one plot per file.  In `eps` mode the whole plot is halved in size; the",
  1396. " fonts are half the given size, and the plot is 5 inches wide and 3.5 inches",
  1397. " high.",
  1398. "",
  1399. " Examples:",
  1400. "",
  1401. "         set term postscript default       # old postscript",
  1402. "         set term postscript enhanced      # old enhpost",
  1403. "         set term postscript landscape 22  # old psbig",
  1404. "         set term postscript eps 14   # old epsf1",
  1405. "         set term postscript eps 22   # old epsf2",
  1406. "         set size 0.7,1.4",
  1407. "         set term post portrait color \"Times-Roman\" 14",
  1408. "2 enhanced postscript",
  1409. "?set terminal postscript enhanced",
  1410. "?enhanced postscript",
  1411. " The syntax used to change fonts and create subscripts and superscripts in",
  1412. " enhanced postscript is as follows:",
  1413. "",
  1414. "@start table - first is interactive cleartext form",
  1415. "  Control      Examples        Explanation",
  1416. "   ^           a^x             superscript",
  1417. "   _           a_x             subscript",
  1418. "   @           @x or a@^b_c    phantom box (occupies no width)",
  1419. "   &           &{space}        inserts space of specified length",
  1420. "#\\multicolumn{3}{|c|}{Enhanced Text Control Codes} \\\\",
  1421. "#Control & Examples & Explanation \\\\ \\hline",
  1422. "#\\verb~^~ & \\verb~a^x~ & superscript\\\\",
  1423. "#\\verb~_~ & \\verb~a_x~ & subscript\\\\",
  1424. "#\\verb~@~ & \\verb~@x or a@^b_c~ & phantom box (occupies no width)\\\\",
  1425. "#\\verb~&~ & \\verb~&{space}~ & inserts space of specified length",
  1426. "%.TE",
  1427. "%.TS",
  1428. "%center box tab ($) ;",
  1429. "%c c l .",
  1430. "%Control$Examples$Explanation",
  1431. "%_",
  1432. "%^$a^x$superscript",
  1433. "%\\&_$a\\&_x$subscript",
  1434. "% @ $ @x or a\\&@^b\\&_c$phantom box (occupies no width)",
  1435. "% & $ &{space}$inserts space of specified length",
  1436. "@end table",
  1437. "",
  1438. " {text} can be used to allow multiple-character text, where only a single",
  1439. " character is expected (e.g., 2^{10}).  To change the font and/or size, use",
  1440. " the full form:  {/[fontname][=fontsize] text}   (For example, {/Symbol=20 G}",
  1441. " is a 20 point GAMMA).  (The '/' character MUST be the first character after",
  1442. " the '{'.)",
  1443. "",
  1444. " The phantom box is useful for a@^b_c to align superscripts and subscripts,",
  1445. " and for overwriting an accent on a letter.  It is common sense to put the",
  1446. " shorter of the two in the phantom box.",
  1447. "",
  1448. " Space equal in length to a string can be inserted using the '&' character.",
  1449. " Thus 'abc&{def}ghi' would produce 'abc   ghi'.",
  1450. "",
  1451. " You can access special symbols numerically by specifying \\character-code (in",
  1452. " octal), e.g., {/Symbol \\245} is the symbol for infinity.",
  1453. "",
  1454. " You can escape control characters using \\, e.g.,  \\\\, \\{, and so on.",
  1455. "",
  1456. " But be aware that strings in double-quotes are parsed differently than those",
  1457. " enclosed in single-quotes.  The major difference is that backslashes may need",
  1458. " to be doubled when in double-quoted strings.",
  1459. "",
  1460. " Examples (these are hard to describe in words---try them!):",
  1461. "         set xlabel 'Time (10^6 {/Symbol m}s'",
  1462. "         set title '{/Symbol=18 \\362@_{/=9.6 0}^{/=12 x}} \\",
  1463. "                    {/Helvetica e^{-{/Symbol m}^2/2} d}{/Symbol m}'"
  1464. END_HELP(post)
  1465. #endif
  1466.